import {observer} from 'mobx-react';
import {observable, toJS} from 'mobx';
import {WeaLeftRightLayout, WeaLocaleProvider, WeaSlideModal, WeaTextarea, WeaPopoverHrm} from 'ecCom';
import {propsComToViewCom} from "../../designer/form/component";
import {Button, message, Spin,Modal} from 'antd';

import FieldError from "../../designer/form/view/field/Error";
import FieldView from "../../designer/form/view/field/View";
import {viewTypes} from "../../../constants/form";
import {
    isAddress,
    isAttachment,
    isDataTable,
    isLayout,
    isPicture,
    isSignature, needValid, isHiddenInput
} from "../../designer/form/component/typeof";

import fillin from "../../../apis/fillin";
import DATAAPI from "../../../apis/data";
import {findDOMNode} from "react-dom";

const { getLabel } = WeaLocaleProvider;

@observer export default class HtmlDataPanel extends React.Component {
  orignalParentComps = null;
  orignalComps = null;

  @observable editRemark = 1;
  @observable editForm = false;
  @observable formid = '';//主表id
  @observable dataId = '';//主表数据id
  @observable isSaving = false;
  @observable remark = '';
  @observable errorCom = null;
  @observable selectedFormid = '';
  @observable selectedDataId = '';

  componentWillReceiveProps() {
    const {comps} = this.props.detailData;
    if(!comps) {
      this.editForm = false;
    }
  }

  componentDidUpdate() {
    const errorcom = toJS(this.errorCom);
    if (errorcom) {
        const wrapperDOM = findDOMNode(this.wrapper);
        const errorComDOM = wrapperDOM.querySelector(`[data-id='${errorcom.uuid}']`);
        this.scrollToError(errorComDOM.parentNode);
        this.autoFocus(errorComDOM);
        this.errorCom = null;
    }
  }

  scrollToError(errorComDOM) {
    if (errorComDOM) {
      const offset = errorComDOM.offsetTop;

      this.scrollSmoothTo(offset);
    }
  }

  scrollSmoothTo(position) {
    if (!window.requestAnimationFrame) {
      window.requestAnimationFrame = function (callback) {
        return setTimeout(callback, 17);
      };
    }
    const $WeaEdcMain = document.querySelector('.wea-edc-fv-main');
    let scrollTop = $WeaEdcMain.scrollTop;
    let step = function () {
      // 距离目标滚动距离
      let distance = position - scrollTop;
      // 目标滚动位置
      scrollTop = scrollTop + distance / 5;
      if (Math.abs(distance) < 1) {
        $WeaEdcMain.scrollTo(0, position);
      } else {
        $WeaEdcMain.scrollTo(0, scrollTop);
        requestAnimationFrame(step);
      }
    };
    step();
  }

  autoFocus(errorComDOM) {
    const focusEle = errorComDOM.querySelector('.wea-edc-has-error select, .wea-edc-has-error input, .wea-edc-has-error textarea');
    if (focusEle) focusEle.focus();
  }

  onEditStateChange(edit) {
    this.editRemark = edit ? 2 : 1;
  }

  onRemarksChange = value => {
    this.remark = value;
  };

  deleteData = () => {
    const {deleteStart} = this;
      Modal.confirm({
          content: getLabel('505984', '是否确认删除？'),
          onOk() {
            deleteStart();
          }
      })
  }

  deleteStart = () => {
    const { reloadData} = this.props;
    const formid = this.selectedFormid;
    const dataId = this.selectedDataId;
    DATAAPI.delete({formid:formid , dataIds:dataId}).then(() => {
      message.success(getLabel('505985', '删除成功'));
      this.onClose();
      reloadData();
    });
  }

  handleRemarksChange = () => {
    const value = this.remark;

    const formData = {};
    formData['remark'] = value;
    formData['formId'] = this.formid;
    formData['dataId'] = this.dataId;

    const { sys } = this.props.detailData;
    sys.remark = value;

    fillin.modifyRemark(formData).then(() => {
      message.success(getLabel('511650','修改成功'))
    }).catch((e) => {
      console.log(e);
    });

    this.onEditStateChange(false);
  };


  renderItem = (com, customProps = {}) => {
    if (!com) return null;

    if (false === com.visible) return null;

    const { errorCom, error } = com;
    let theError = '';

    if (customProps.hasOwnProperty('error')) {
        theError = customProps.error;
    } else if (errorCom) {
        theError = errorCom.error;
    } else {
        theError = error;
    }

    return this.getFieldView(com, customProps, theError);
  }

  getLeftMainView(components, parentComps = []) {
    if(!components) return null;
    if (parentComps && !this.orignalParentComps) {
      this.orignalParentComps = _.cloneDeep(toJS(parentComps));
    }

    if (!this.orignalComps) {
      this.orignalComps = _.cloneDeep(toJS(components))
    }
    

    const {detailData} = this.props;
    const {formmodeId, isSetCategory} = detailData;
    components.filter(com => (isAttachment(com) || isPicture(com) || isSignature(com))).forEach(com => {
      com.config.isSetCategory = isSetCategory;
      com.config.formmodeId = formmodeId || '';
    });
    components = components.filter(com => !isHiddenInput(com));

    const setComVal = com => {
      const find = components.find(c => c.uuid === com.uuid);
      const val = find && find.value || '';
      val && (com.value = val);
      return val;
    };

    // 地址特殊处理
    parentComps.forEach(com => {
      if (isAddress(com)) {
        const { province, city, district, detail } = com.config;
        com.value = setComVal(province) + setComVal(city) + setComVal(district) + setComVal(detail);
      }

      if (isDataTable(com)) {
            let { coms } = com.config;
            if (coms) {
                com.config.defaultRowValue = coms.map(com => com && propsComToViewCom(com).value);
            }
            com.config.errors =  com.config.errors||[];
        }
    });

    return (
      <div className='wea-edc-fv-main' ref={wrapper => this.wrapper = wrapper}>
        <div className='wea-edc-fv-body clearfix'>
          {components.filter(com => (!com.pid || isLayout(parentComps.find(p => p.uuid === com.pid)))).map(com => (
            <FieldError ecId={`${this && this.props && this.props.ecId || ''}_FieldError@lzfccv@${com.uuid}`} key={com.uuid} error={com.errorCom ? com.errorCom.error : com.error} >
              {this.getFieldView(com)}
            </FieldError>
          ))}

          {parentComps.filter(com => isAddress(com) || isDataTable(com)).map(com => (
            <FieldError ecId={`${this && this.props && this.props.ecId || ''}_FieldError@2kf0vt@${com.uuid}`} key={com.uuid} error={com.errorCom ? com.errorCom.error : com.error} >
              {this.getFieldView(com)}
            </FieldError>
          ))}
        </div>
      </div>
    )
  }

  getFieldView(com, customProps = {},error) {
      if(!com.config) return ;
      const viewType = !this.editForm && viewTypes.READONLY || viewTypes.PC;
      const errmsg = !error ? null : <p className='wea-edc-errmsg' style={{position:'relative',left:0,bottom:0}}>{error}</p>;
      const propViewType = customProps.viewType ? customProps.viewType : '';
      const comProps = {
          viewType: propViewType || viewType,
          key: com.uuid,
          field: com,
          className: errmsg && 'wea-edc-has-error',
          children: errmsg
      };
      if(com.config.complex) {
      return (
        <FieldView ecId={`${this && this.props && this.props.ecId || ''}_FieldView@elgcvg`}
          key={com.uuid}
          viewType={viewType}
          field={com}
          isShowLock={true}
          {...comProps}
          onChange={(uuid, value) => {
            this.handleValChange(value, uuid);
          }}
        />
      );
    }

    // 布局插件，如明细子表
    if (com.config.coms) {
      return (
        <FieldView ecId={`${this && this.props && this.props.ecId || ''}_FieldView@us6qry`}
          viewType={viewType}
          field={com}
           {...comProps}
          onChange={(value) => {
            if (viewType !== viewTypes.READONLY) {
              this.handleValChange(value, com.uuid)
            }
          }}
          renderItem={this.renderItem}
        />
      );
    }

    return (
      <FieldView ecId={`${this && this.props && this.props.ecId || ''}_FieldView@vumxzk`}
        key={com.uuid}
        viewType={viewType}
        field={com}
        isShowLock={true}
        onChange={(value) => {
          this.handleValChange(value, com.uuid);
        }}
        dataPanel={true}
        {...customProps}
        {...comProps}
      />
    );
  }

  handleValChange(value, uuid) {
    const {detailData} = this.props;
    const {parentComps, comps} = detailData;
    const find = comps.find(c => c.uuid === uuid);
    const parent = parentComps.find(c => c.uuid === uuid);
    let pCom;

    if (find) {
      find.value = value;
      find.error = "";
      pCom = parentComps.find(c => c.uuid === find.pid);
    }
    if (parent && isDataTable(parent)) {
          parent.value = value;
          parent.config.errors = [];
          if (!find) {
              comps.push({uuid, value});
          }
      }

    if (pCom && pCom.config.complex) {
        pCom.error = '';
      }
    this.props.detailData.comps = toJS(comps);
  }


  isComValid = com => {
      com.valid = true;
      com.error = '';

      const validate = (rule, field) =>{
          const valid = rule.validate(field);
          const error = !valid ? rule.error(field) : '';
          return { valid, error };
      };
      com.rules.every(rule => {
          const { error, valid } = validate(rule, com);

          if (valid) return true;

          com.valid = false;
          com.error = error;
          
      });
      return com.valid;
  };
  
  isFormValid = (comps,parentComps) =>{
        const coms = [...comps,...parentComps].filter(com => com.config)
            .map(com => Object.assign(propsComToViewCom(com),{value:com.value}))
            .filter(needValid);

        let errorCom = coms.find(com => !this.isComValid(com));
        if (errorCom) {
            if(isDataTable(errorCom)){
                const com = parentComps.find(com => errorCom.uuid === com.uuid);
                com.config.errors = errorCom.config.errors;
          }else{
            if(errorCom.pid) {
              const parentCom = parentComps.find(com => errorCom.pid === com.uuid);
              parentCom.error = errorCom.error;
            }
              const com = comps.find(com => errorCom.uuid === com.uuid || errorCom.pid === com.uuid);
              com.error = errorCom.error;
            }
        }
        return {valid: !errorCom,errorCom};
  };

  onSubmit = () => {
    if(this.isSaving) return;
    this.isSaving = true;

    const { detailData, reloadData } = this.props;
    const { comps,parentComps } = detailData;
    const { valid,errorCom } = this.isFormValid(comps,parentComps);
    if(!valid){
        detailData.comps = toJS(comps);
        detailData.parentComps =  toJS(parentComps);
        this.errorCom = errorCom;
        this.isSaving = false;
        return;
    }
    const newComs = comps.map(com => {
      let { uuid, value } = com;
      if ((isAttachment(com) || isPicture(com)) && value) {
        let docIds = [];
        value.forEach(({ docid }) => {
          docid > 0 && (docIds.push(docid));
        });
        value = docIds.join(',');
      }

      if (isSignature(com) && value) {
        value.docid && (value = value.docid);
      }

      return { uuid, value };
    });

    const formData = {};
    formData['formid'] = this.formid;
    formData['id'] = this.dataId;
    formData['isEdit'] = true;
    formData['datas'] = JSON.stringify(newComs);

    fillin.modifyData(formData).then(() => {
      message.success(getLabel('511650','修改成功'));
      reloadData();
      this.editForm = false;
      this.isSaving = false;
    }).catch(() => {
      message.error(getLabel('511657','修改数据异常'));
      this.isSaving = false;
    });
  };

  onClose = () => {
    const { close } = this.props;
    this.editForm = false;
    this.onEditStateChange(false);
    close();
  };

  renderContent() {
    const { props, editRemark, isSaving } = this;
    const { detailData, rightLevel } = props;
    const { comps, sys, parentComps } = detailData;
    const editRight = rightLevel == 2;

    return (
      <Spin ecId={`${this && this.props && this.props.ecId || ''}_Spin@ya0ymf`} spinning={!comps || isSaving}>
        <WeaLeftRightLayout ecId={`${this && this.props && this.props.ecId || ''}_WeaLeftRightLayout@vtgom8`}
          leftWidth={550}
          showBtn={false}
          leftCom={this.getLeftMainView(comps, toJS(parentComps))}
        >
          <div className="modal-right-wrapper">
            <div className="modal-right-header">
              <div className="title">{getLabel('502654', '基本信息')}</div>
              <div className="function-button">
              </div>
            </div>
            <div className="entry-info-section">
              <dl>
                <dt>{getLabel('511658','序号：')}</dt><dd>{sys.id}</dd>
              </dl>
              {
                sys.extendData && 
                <dl>
                  <dt>{getLabel('516741', '扩展属性：')}</dt><dd>{sys.extendData}</dd>
                </dl>
              }
              <dl>
                <dt>{getLabel('511659', '提交人：')}</dt><dd>
                  <WeaPopoverHrm ecId={`${this && this.props && this.props.ecId || ''}_WeaPopoverHrm@ajamau`} />
                  {
                    sys.creatorId &&
                    <a
                      href={`javaScript:openhrm(${sys.creatorId});`}
                      onClick={e => window.pointerXY(e)}
                      title={sys.creator}
                    >
                      {sys.creator}
                    </a>
                  }
                </dd>
              </dl>
              <dl>
            <dt>{getLabel('511660','提交时间：')}</dt><dd>{sys.createdate} {sys.createtime}{sys.statisticsdate && ' (' + getLabel('26927', '补交') + sys.statisticsdate + ')'}</dd>
              </dl>
              <dl>
                <dt>{getLabel('511680','填写设备：')}</dt><dd>{sys.clientdevice}</dd>
              </dl>
              <dl>
                <dt>{getLabel('511681','操作系统：')}</dt><dd>{sys.clientos}</dd>
              </dl>
              <dl>
                <dt>{getLabel('511682','浏览器：')}</dt><dd>{sys.clientbrowser}</dd>
              </dl>
              <dl>
                <dt>{getLabel('511683','IP：')}</dt><dd>{sys.ip}</dd>
              </dl>
            </div>
            <div className="entry-remark-split-line"/>

            {
              sys.wxopenid ?
                <div>
                  <div className="modal-right-header">{getLabel('511684','微信信息')}</div>
                  <div className="weixin-info">
                    <img src={sys.wxheadimgurl} className="avatar"/>
                    <div className="info-container">
                      <span>{getLabel('511671','昵称：')}{sys.wxnickname}</span>
                      <br/>
                      <span>{getLabel('511672','性别：')}{sys.wxsex}</span>
                      <span>{getLabel('511673','省市：')}{sys.wxprovince} {sys.wxcity} </span>
                    </div>
                  </div>
                  <div className="entry-remark-split-line"/>
                </div>
                : null
            }

            <div className="entry-remark-container">
              <div className="edit-container">
                {
                  (editRight && !sys.remark) ?
                    <a className="add-remark" onClick={() => { this.onEditStateChange(true) }}>
                      {(editRemark === 1) && <i className="icon-edc-f-edit wea-edc-input-icon"/>}
                      {getLabel('511674','添加备注')}
                      </a>
                    :
                    <div className="modal-right-header">{getLabel('511675','数据备注')}</div>
                }
              </div>
              <WeaTextarea ecId={`${this && this.props && this.props.ecId || ''}_WeaTextarea@8x7puh`}
                style={{ height: '150' }}
                viewAttr={editRight ? editRemark : 1}
                value={sys.remark}
                onChange={this.onRemarksChange}
                ref={'remark'} />
              {editRight ?
                editRemark != 1 &&
                <div><span onClick={this.handleRemarksChange} className="edit-btn edit-btn-save">{getLabel('506963','保存')}</span>
                  <span className="edit-btn" onClick={() => { this.onEditStateChange(false) }}>{getLabel('31129', '取消')}</span></div>
                || (sys.remark && <span onClick={() => { this.onEditStateChange(true) }} className="edit-btn">{getLabel(504304, "修改")}</span>)
                : null
              }
            </div>
          </div>
        </WeaLeftRightLayout>
      </Spin>
    );
  }

  render() {
    const { props, isSaving, editForm, onSubmit, onClose, deleteData } = this;
    const { visible, detailData, rightLevel } = props;
    const { sys } = detailData;

    const editRight = rightLevel == 2;
    const buttons = editRight ? (!editForm && [
      (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@2ufuwl@deleteData`} type="primary" loading={isSaving} onClick={deleteData}>{getLabel(502286, '删除')}</Button>),
      (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@vv0gok@editForm`} type="primary" loading={isSaving} onClick={() => { this.editForm = true }}>{getLabel(504304, "修改")}</Button>),
      (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@hc0zez@onClose`} type="ghost" onClick={onClose}>{getLabel(31129, "取消")}</Button>)
    ] || [
      isSaving ? (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@rnh9vn@submit`} type="primary" loading={isSaving} disabled>{getLabel('502502','提交')}</Button>) : (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@p2g90q@$submit`} type="primary" loading={isSaving} onClick={onSubmit}>{getLabel('502502','提交')}</Button>),
        (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@80ue86@cancel`} type="ghost" onClick={() => { 
          if (this.orignalComps) {
            this.props.detailData.comps = toJS(this.orignalComps);
          }

          if (this.orignalParentComps) {
            this.props.detailData.parentComps = toJS(this.orignalParentComps);
          }
   
          this.editForm = false 
        }}>{getLabel(31129, "取消")}</Button>)
      ]) : [
        (<Button ecId={`${this && this.props && this.props.ecId || ''}_Button@rwicki@close`} type="ghost" onClick={onClose}>{getLabel('511699','关闭')}</Button>)
      ];

    this.formid = sys.formid;
    this.dataId = sys.id;
    this.selectedDataId = sys.selectedDataId;
    this.selectedFormid = sys.selectedFormid;
    return (
      <WeaSlideModal ecId={`${this && this.props && this.props.ecId || ''}_WeaSlideModal@mje4iu`}
        onClose={onClose}
        className="edc-html-datapanel"
        visible={visible}
        width={'800'}
        height={100}
        direction={'right'}
        measureY={'%'}
        title={<div><div className="title-close-div" onClick={onClose}><span className="title-close"/></div><div className={'title-btns'}>{buttons}</div></div>}
        content={this.renderContent()}
        hasScroll={false}
      >
      </WeaSlideModal>
    );
  }
}